package com.bs.service;


import com.bs.domain.ServiceInfo;
import com.bs.domain.SvcExecuteInfo;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.aggregations.metrics.max.InternalMax;
import org.elasticsearch.search.aggregations.metrics.max.MaxBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class QuestionCountService {

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    private String partition;
    private String logmsg;
    private String startTime;
    private String endTime;
    private String code;
    private String active;

    private SearchResponse getResponse() {
        String index = "logstash-*-" + active + "-svcsql-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", logmsg));
        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        } else {
            if (("4. service end.").equals(logmsg)){
                // !svc:ep* && !uid:"xcom"
              builder.mustNot(QueryBuilders.wildcardQuery("svc","ep?*"))
                     .mustNot(QueryBuilders.termQuery("uid","xcom"));
            }
        }
        if (!code.equals("")) {
            index = "logstash-" + code + "-svcsql-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("category", "SVCSQL"))
                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder svcAgg = AggregationBuilders.terms("services").field("svc")
            .size(10)
            .order(Terms.Order.aggregation("svc_exec_time", false));
        MaxBuilder maxAgg = AggregationBuilders.max("svc_exec_time").field("exec_time");
        TermsBuilder partitionAgg = AggregationBuilders.terms("partition").field("partition");
      //  TermsBuilder uidAgg = AggregationBuilders.terms("uid").field("uid");
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(svcAgg.subAggregation(maxAgg).subAggregation(partitionAgg))
            .execute().actionGet();
    }

    /**
     *   查询 慢服务与慢电文 Top10
     * @param partition
     * @param logmsg
     * @param startTime
     * @param endTime
     * @param code
     * @param active
     * @return
     */
    public List<ServiceInfo> slowServiceOrCommTop10Resource(String partition, String logmsg, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.logmsg = logmsg;
        this.code = code;
        this.active = active;
        List<ServiceInfo> serviceInfoList = new ArrayList<>();
        SearchResponse response = getResponse();
        if (response.getHits().totalHits() != 0) {
        StringTerms svcAgg = (StringTerms) response.getAggregations().asMap().get("services");
        Iterator<Terms.Bucket> iterator = svcAgg.getBuckets().iterator();
        while (iterator.hasNext()) {
            Terms.Bucket next = iterator.next();
            String service = next.getKeyAsString();
            InternalMax maxTime = (InternalMax) next.getAggregations().asMap().get("svc_exec_time");
            double maxValue = maxTime.getValue();
            ServiceInfo slowServiceInfo = new ServiceInfo(service, maxValue);
            serviceInfoList.add(slowServiceInfo);
        }
        }
        return serviceInfoList;

    }


}
